package com.my.study.controller;

import com.mongodb.bulk.BulkWriteResult;
import com.my.study.common.base.JsonResult;
import com.my.study.entity.UserEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.UntypedExampleMatcher;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: yidujun
 * @create: 2021/07/28 13:44
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    MongoTemplate mongoTemplate;

    @RequestMapping("/save")
    public JsonResult<UserEntity> saveUser(@RequestBody UserEntity user) {
        UserEntity result = mongoTemplate.insert(user, "user");
        return JsonResult.buildSuccess(result);
    }

    @RequestMapping("/find/{id}")
    public JsonResult findUser(@PathVariable Long id) {
        Query query = new Query(Criteria.where("id").in(id));
        UserEntity user = mongoTemplate.findOne(query, UserEntity.class, "user");
        log.debug("user: {}", user);
        return JsonResult.buildSuccess(user);
    }

    /**
     * 多条件查询
     *
     * @return
     */
    @RequestMapping("/find")
    public JsonResult findUserBy() {
        /**
         * 查询集合user满足：
         *  userName = "qaz" 或者  id >= 4
         */
        Criteria criteria = new Criteria();

        Criteria c1 = Criteria.where("userName").is("qaz");
        Criteria c2 = Criteria.where("id").gte(4);
        criteria.orOperator(c1, c2);

        Query query = new Query(criteria);

        List<UserEntity> users = mongoTemplate.find(query, UserEntity.class, "user");
        log.debug("users: {}", users.toString());
        return JsonResult.buildSuccess(users);
    }

    /**
     * 定义规则查询
     *
     * 可参考博客：
     *  1）官网：https://docs.spring.io/spring-data/mongodb/docs/3.2.3/reference/html/#query-by-example
     *  2）其他：https://www.logicbig.com/tutorials/spring-framework/spring-data/query-example-matchers.html
     *
     * @param userName
     * @return
     */
    @RequestMapping("/example/{userName}")
    public JsonResult like(@PathVariable String userName) {
        UserEntity userEntity = new UserEntity();
        userEntity.setUserName(userName);

        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withMatcher("nameUser", ExampleMatcher.GenericPropertyMatchers.contains())
//                .withIgnorePaths("id", "pwd")
                ;

        Example<UserEntity> example = Example.of(userEntity, exampleMatcher);

        Query query = new Query(new Criteria().alike(example));

        List<UserEntity> users = mongoTemplate.find(query, UserEntity.class, "user");
        log.debug("users: {}", users.toString());
        return JsonResult.buildSuccess(users);
    }

    @RequestMapping("/batchSave")
    public JsonResult batchSaveUser() {
        BulkOperations ops = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, UserEntity.class, "user");
        ops.insert(getUsers());
        BulkWriteResult execute = ops.execute();

        int insertedCount = execute.getInsertedCount();
        boolean wasAcknowledged = execute.wasAcknowledged();

        Map<String, Object> result = new HashMap<>(6);
        result.put("counts", insertedCount);
        result.put("wasAcknowledged", wasAcknowledged);

        return JsonResult.buildSuccess(result);
    }

    private List<UserEntity> getUsers() {
        List<UserEntity> list = new ArrayList<>();
        list.add(new UserEntity(2L, "qaz", "123456"));
        list.add(new UserEntity(3L, "wsx", "123456"));
        list.add(new UserEntity(4L, "eec", "123456"));
        list.add(new UserEntity(5L, "rfdd", "123456"));

        return list;
    }

}
